#include <utils/account.h>


namespace AccountManagerUtils {

//! Default constructor
Account::Account() : name_(""), number_(""), bank_(NULL) {}

//! Copy constructor
Account::Account(const Account& rhs) :
	name_(rhs.name_), number_(rhs.number_), bank_(rhs.bank_), owners_(rhs.owners_) {}

//! Constructor from a name, a number, a bank and one owner
Account::Account(const String& name, const String& number, const Bank* bank, const Person* owner) : name_(name), number_(number), bank_(bank) {
	if ( owner != NULL ) {
		owners_.push_back( owner );
	}
}

//! Constructor from a name, a number, a bank and a list of owners
Account::Account(const String& name, const String& number, const Bank* bank, const List<const Person*>& owners) :
	name_(name), number_(number), bank_(bank), owners_(owners) {}

//! Destructor
Account::~Account() {}

//! Copy constructor
Account& Account::operator=(const Account& rhs) {
	if ( &rhs != this ) {
		name_ = rhs.name_;
		number_ = rhs.number_;
		bank_ = rhs.bank_;
		owners_ = rhs.owners_;
	}
	return *this;
}

//! Comparison operator
bool Account::operator==(const Account& rhs) const {
	if ( name_ != rhs.name_ ) return false;
	if ( number_ != rhs.number_ ) return false;
	if ( bank_ != rhs.bank_ ) return false;
	if ( owners_.size() != rhs.owners_.size() ) return false;
	for ( List<const Person*>::const_iterator it = owners_.begin(); it != owners_.end(); ++it ) {
		bool found = false;
		for ( List<const Person*>::const_iterator rit = rhs.owners_.begin(); rit != rhs.owners_.end(); ++rit ) {
			if ( (*rit) != (*it) ) continue;
			found = true;
			break;
		}
		if ( found == false ) return false;
	}
	return true;
}

//! Difference operator
bool Account::operator!=(const Account& rhs) const {
	if ( name_ != rhs.name_ ) return true;
	if ( number_ != rhs.number_ ) return true;
	if ( bank_ != rhs.bank_ ) return true;
	if ( owners_.size() != rhs.owners_.size() ) return true;
	for ( List<const Person*>::const_iterator it = owners_.begin(); it != owners_.end(); ++it ) {
		bool found = false;
		for ( List<const Person*>::const_iterator rit = rhs.owners_.begin(); rit != rhs.owners_.end(); ++rit ) {
			if ( (*rit) != (*it) ) continue;
			found = true;
			break;
		}
		if ( found == false ) return true;
	}
	return false;
}

//! Accessor to the name of the account (read-write)
String& Account::name() {
	return name_;
}

//! Accessor to the name of the account (read only)
const String& Account::name() const {
	return name_;
}

//! Accessor to the number of the account (read-write)
String& Account::number() {
	return number_;
}

//! Accessor to the number of the account (read only)
const String& Account::number() const {
	return number_;
}

//! Change the bank of the account
void Account::set_bank(const Bank* bank) {
	bank_ = bank;
}

//! Accessor to the name of the account (read only)
const Bank* Account::bank() const {
	return bank_;
}

//! Accessor to the owners of the account (read-write)
List<const Person*>& Account::owners() {
	return owners_;
}

//! Accessor to the owners of the account (read only)
const List<const Person*>& Account::owners() const {
	return owners_;
}

//===========================================================

//! Initialize the account lib instance
AccountLib* AccountLib::instance_ = NULL;

//! Find a account with given name, if any
const Account* AccountLib::find_account(const String& name, const String& number, const Bank* bank, List<const Person*>& owners) {
	QSet<Account>::iterator it = instance()->accounts_.find( Account(name,number,bank,owners) );
	if ( it == instance()->accounts_.end() ) {
		return NULL;
	}
	return &(*it);
}

//! Get the list of accounts
const Set<Account>& AccountLib::accounts() {
	return instance()->accounts_;
}

//! Destructor
AccountLib::~AccountLib() {}

//! Constructor
AccountLib::AccountLib() {}

//! Find or create the instance of AccountLib
AccountLib* AccountLib::instance() {
	if ( instance_ == NULL ) {
		instance_ = new AccountLib();
	}
	return instance_;
}

} // namespace AccountManagerUtils

